"""
Chinese Zodiac MCP Service

This service provides Chinese zodiac (生肖) calculation functionality.
It takes year and month as input and returns the corresponding zodiac sign.
"""

from datetime import datetime
from typing import Dict, List, Optional
from enum import Enum


class ChineseZodiac(Enum):
    """Chinese Zodiac signs with their attributes"""
    RAT = "鼠"
    OX = "牛"
    TIGER = "虎"
    RABBIT = "兔"
    DRAGON = "龙"
    SNAKE = "蛇"
    HORSE = "马"
    GOAT = "羊"
    MONKEY = "猴"
    ROOSTER = "鸡"
    DOG = "狗"
    PIG = "猪"


class ZodiacService:
    """
    Chinese Zodiac calculation service
    """

    def __init__(self):
        # Zodiac order for calculation
        self.zodiac_order = [
            ChineseZodiac.RAT,
            ChineseZodiac.OX,
            ChineseZodiac.TIGER,
            ChineseZodiac.RABBIT,
            ChineseZodiac.DRAGON,
            ChineseZodiac.SNAKE,
            ChineseZodiac.HORSE,
            ChineseZodiac.GOAT,
            ChineseZodiac.MONKEY,
            ChineseZodiac.ROOSTER,
            ChineseZodiac.DOG,
            ChineseZodiac.PIG
        ]

        # Zodiac attributes for detailed information
        self.zodiac_attributes = {
            ChineseZodiac.RAT: {
                "years": [2008, 1996, 1984, 1972, 1960],
                "traits": "聪明、机智、适应性强",
                "lucky_numbers": [2, 3],
                "lucky_colors": ["蓝色", "红色"]
            },
            ChineseZodiac.OX: {
                "years": [2009, 1997, 1985, 1973, 1961],
                "traits": "勤劳、可靠、诚实",
                "lucky_numbers": [1, 9],
                "lucky_colors": ["蓝色", "红色", "紫色"]
            },
            ChineseZodiac.TIGER: {
                "years": [2010, 1998, 1986, 1974, 1962],
                "traits": "勇敢、自信、有领导力",
                "lucky_numbers": [1, 3, 4],
                "lucky_colors": ["蓝色", "灰色", "橙色"]
            },
            ChineseZodiac.RABBIT: {
                "years": [2011, 1999, 1987, 1975, 1963],
                "traits": "温和、优雅、有礼貌",
                "lucky_numbers": [3, 4, 6],
                "lucky_colors": ["红色", "粉色", "紫色", "蓝色"]
            },
            ChineseZodiac.DRAGON: {
                "years": [2012, 2000, 1988, 1976, 1964],
                "traits": "自信、有活力、有魅力",
                "lucky_numbers": [1, 6, 7],
                "lucky_colors": ["金色", "银色", "灰色"]
            },
            ChineseZodiac.SNAKE: {
                "years": [2013, 2001, 1989, 1977, 1965],
                "traits": "智慧、敏锐、有洞察力",
                "lucky_numbers": [2, 8, 9],
                "lucky_colors": ["黑色", "红色", "黄色"]
            },
            ChineseZodiac.HORSE: {
                "years": [2014, 2002, 1990, 1978, 1966],
                "traits": "活泼、自由、有活力",
                "lucky_numbers": [2, 3, 7],
                "lucky_colors": ["棕色", "黄色", "紫色"]
            },
            ChineseZodiac.GOAT: {
                "years": [2015, 2003, 1991, 1979, 1967],
                "traits": "温和、善良、有艺术气质",
                "lucky_numbers": [2, 7],
                "lucky_colors": ["棕色", "红色", "紫色"]
            },
            ChineseZodiac.MONKEY: {
                "years": [2016, 2004, 1992, 1980, 1968],
                "traits": "聪明、机智、有幽默感",
                "lucky_numbers": [1, 7, 8],
                "lucky_colors": ["白色", "蓝色", "金色"]
            },
            ChineseZodiac.ROOSTER: {
                "years": [2017, 2005, 1993, 1981, 1969],
                "traits": "勤奋、诚实、有责任心",
                "lucky_numbers": [5, 7, 8],
                "lucky_colors": ["金色", "棕色"]
            },
            ChineseZodiac.DOG: {
                "years": [2018, 2006, 1994, 1982, 1970],
                "traits": "忠诚、可靠、有正义感",
                "lucky_numbers": [3, 4, 9],
                "lucky_colors": ["绿色", "红色", "紫色"]
            },
            ChineseZodiac.PIG: {
                "years": [2019, 2007, 1995, 1983, 1971],
                "traits": "诚实、善良、有同情心",
                "lucky_numbers": [2, 5, 8],
                "lucky_colors": ["黄色", "灰色", "棕色", "金色"]
            }
        }

    def _get_chinese_new_year_date(self, year: int) -> datetime:
        """
        Get Chinese New Year date for a given year
        This is a simplified calculation - in reality, Chinese New Year varies each year

        Args:
            year: Gregorian year

        Returns:
            datetime: Chinese New Year date for that year
        """
        # Simplified calculation - actual dates vary
        # This is an approximation
        chinese_new_year_dates = {
            2000: datetime(2000, 2, 5),
            2001: datetime(2001, 1, 24),
            2002: datetime(2002, 2, 12),
            2003: datetime(2003, 2, 1),
            2004: datetime(2004, 1, 22),
            2005: datetime(2005, 2, 9),
            2006: datetime(2006, 1, 29),
            2007: datetime(2007, 2, 18),
            2008: datetime(2008, 2, 7),
            2009: datetime(2009, 1, 26),
            2010: datetime(2010, 2, 14),
            2011: datetime(2011, 2, 3),
            2012: datetime(2012, 1, 23),
            2013: datetime(2013, 2, 10),
            2014: datetime(2014, 1, 31),
            2015: datetime(2015, 2, 19),
            2016: datetime(2016, 2, 8),
            2017: datetime(2017, 1, 28),
            2018: datetime(2018, 2, 16),
            2019: datetime(2019, 2, 5),
            2020: datetime(2020, 1, 25),
            2021: datetime(2021, 2, 12),
            2022: datetime(2022, 2, 1),
            2023: datetime(2023, 1, 22),
            2024: datetime(2024, 2, 10),
            2025: datetime(2025, 1, 29),
        }

        # For years not in the mapping, use approximation
        if year not in chinese_new_year_dates:
            # Chinese New Year is usually between January 21 and February 20
            # Use February 1 as a rough approximation
            return datetime(year, 2, 1)

        return chinese_new_year_dates[year]

    def get_zodiac_sign(self, year: int, month: int = None, day: int = None) -> Dict[str, any]:
        """
        Get Chinese zodiac sign for a given date

        Args:
            year: Gregorian year
            month: Gregorian month (1-12), optional
            day: Gregorian day (1-31), optional

        Returns:
            Dict: Zodiac information including sign, attributes, and calculation details
        """
        try:
            # Validate input
            if not isinstance(year, int) or year < 1900 or year > 2100:
                return {"error": "无效的年份，请输入1900-2100之间的年份"}

            # If only year is provided, we'll calculate based on Chinese New Year
            if month is None:
                # For year-only queries, we need to determine if the date is before or after Chinese New Year
                chinese_new_year = self._get_chinese_new_year_date(year)

                # Default to mid-year (July 1) for year-only queries
                query_date = datetime(year, 7, 1)

                if query_date >= chinese_new_year:
                    # After Chinese New Year, use this year's zodiac
                    zodiac_year = year
                else:
                    # Before Chinese New Year, use previous year's zodiac
                    zodiac_year = year - 1
            else:
                # Validate month
                if not isinstance(month, int) or month < 1 or month > 12:
                    return {"error": "无效的月份，请输入1-12之间的数字"}

                # Create date (use day 1 if day not provided)
                if day is None:
                    day = 1
                elif not isinstance(day, int) or day < 1 or day > 31:
                    return {"error": "无效的日期，请输入1-31之间的数字"}

                try:
                    query_date = datetime(year, month, day)
                except ValueError:
                    return {"error": "无效的日期"}

                # Find Chinese zodiac year
                chinese_new_year = self._get_chinese_new_year_date(year)

                if query_date >= chinese_new_year:
                    zodiac_year = year
                else:
                    zodiac_year = year - 1

            # Calculate zodiac index (2008 is Year of the Rat, which is index 0)
            base_year = 2008  # Year of the Rat
            zodiac_index = (zodiac_year - base_year) % 12

            zodiac_sign = self.zodiac_order[zodiac_index]

            # Get zodiac attributes
            attributes = self.zodiac_attributes[zodiac_sign]

            # Build response
            result = {
                "input": {
                    "year": year,
                    "month": month,
                    "day": day
                },
                "zodiac_year": zodiac_year,
                "zodiac_sign": zodiac_sign.value,
                "zodiac_english": zodiac_sign.name,
                "attributes": attributes,
                "chinese_new_year": self._get_chinese_new_year_date(zodiac_year).strftime("%Y年%m月%d日")
            }

            return result

        except Exception as e:
            return {"error": f"计算生肖时出错: {str(e)}"}

    def get_zodiac_by_year(self, year: int) -> Dict[str, any]:
        """
        Get zodiac sign by year only (simplified method)

        Args:
            year: Gregorian year

        Returns:
            Dict: Zodiac information
        """
        return self.get_zodiac_sign(year)

    def get_all_zodiac_signs(self) -> List[Dict[str, any]]:
        """
        Get all zodiac signs with their information

        Returns:
            List[Dict]: List of all zodiac signs with attributes
        """
        result = []
        for zodiac in ChineseZodiac:
            info = {
                "sign": zodiac.value,
                "english": zodiac.name,
                "attributes": self.zodiac_attributes[zodiac]
            }
            result.append(info)
        return result

    def get_compatibility(self, zodiac1: str, zodiac2: str) -> Dict[str, any]:
        """
        Get compatibility between two zodiac signs

        Args:
            zodiac1: First zodiac sign (Chinese character)
            zodiac2: Second zodiac sign (Chinese character)

        Returns:
            Dict: Compatibility information
        """
        # Simple compatibility matrix
        compatibility_matrix = {
            ("鼠", "龙"): "很好",
            ("鼠", "猴"): "很好",
            ("鼠", "牛"): "好",
            ("牛", "蛇"): "很好",
            ("牛", "鸡"): "很好",
            ("牛", "鼠"): "好",
            ("虎", "马"): "很好",
            ("虎", "狗"): "很好",
            ("虎", "猪"): "好",
            ("兔", "羊"): "很好",
            ("兔", "猪"): "很好",
            ("兔", "狗"): "好",
            ("龙", "猴"): "很好",
            ("龙", "鼠"): "很好",
            ("龙", "鸡"): "好",
            ("蛇", "鸡"): "很好",
            ("蛇", "牛"): "很好",
            ("蛇", "猴"): "好",
            ("马", "狗"): "很好",
            ("马", "虎"): "很好",
            ("马", "羊"): "好",
            ("羊", "猪"): "很好",
            ("羊", "兔"): "很好",
            ("羊", "马"): "好",
            ("猴", "鼠"): "很好",
            ("猴", "龙"): "很好",
            ("猴", "蛇"): "好",
            ("鸡", "牛"): "很好",
            ("鸡", "蛇"): "很好",
            ("鸡", "龙"): "好",
            ("狗", "虎"): "很好",
            ("狗", "马"): "很好",
            ("狗", "兔"): "好",
            ("猪", "兔"): "很好",
            ("猪", "羊"): "很好",
            ("猪", "虎"): "好",
        }

        # Check if both signs are valid
        valid_signs = [zodiac.value for zodiac in ChineseZodiac]
        if zodiac1 not in valid_signs or zodiac2 not in valid_signs:
            return {"error": "无效的生肖"}

        # Get compatibility
        compatibility = compatibility_matrix.get((zodiac1, zodiac2), "一般")
        reverse_compatibility = compatibility_matrix.get((zodiac2, zodiac1), "一般")

        return {
            "zodiac1": zodiac1,
            "zodiac2": zodiac2,
            "compatibility": compatibility,
            "reverse_compatibility": reverse_compatibility,
            "overall": "很好" if compatibility == "很好" or reverse_compatibility == "很好" else compatibility
        }


# Global service instance
zodiac_service = ZodiacService()


def get_zodiac_sign(year: int, month: int = None, day: int = None) -> Dict[str, any]:
    """
    Convenience function to get zodiac sign

    Args:
        year: Gregorian year
        month: Gregorian month (1-12), optional
        day: Gregorian day (1-31), optional

    Returns:
        Dict: Zodiac information
    """
    return zodiac_service.get_zodiac_sign(year, month, day)


def get_all_zodiac_signs() -> List[Dict[str, any]]:
    """
    Convenience function to get all zodiac signs

    Returns:
        List[Dict]: All zodiac signs with attributes
    """
    return zodiac_service.get_all_zodiac_signs()


def get_zodiac_compatibility(zodiac1: str, zodiac2: str) -> Dict[str, any]:
    """
    Convenience function to get zodiac compatibility

    Args:
        zodiac1: First zodiac sign
        zodiac2: Second zodiac sign

    Returns:
        Dict: Compatibility information
    """
    return zodiac_service.get_compatibility(zodiac1, zodiac2)